﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using DevExpress.Web.ASPxEditors;
using DevExpress.Web.ASPxGridView;
using MLY.Dal;
using System.Drawing;
using MLY.Bll;

namespace MLY
{
    public class EditFormControl
    {
        public ASPxTextBoxBase mControl;
        public string mFieldName;
    }

    public class EditFormDictionary : Dictionary<string, EditFormControl>
    {
    }

    public class InventoryEditForm : ITemplate
    {
        private const int mColumnCount = 6;
        private const int mHalfColumnCount = mColumnCount / 2;
        private const int mFirstCol = 1;
        private const int mRowCount = 14;
        private const int mGapWidth = 50;
        private const int mLabelWidth = 190;
        private const int mEditWidth = 300;

        public const string mSentQuantityTextBox = "SentQuantityTextBox";
        public const string mContractorIdTextBox = "ContractorIdTextBox";
        public const string mContractorIdComboBox = "ContractorIdComboBox";
        public const string mClientWorkOrderNumberTextBox = "ClientWorkOrderNumberTextBox";
        public const string mContractorWorkOrderNumberTextBox = "ContractorWorkOrderNumberTextBox";
        public const string mQuantityTextBox = "QuantityTextBox";

        public EditFormDictionary mEditFormDictionary;

        public void InstantiateIn(Control container)
        {
            mEditFormDictionary = new EditFormDictionary();

            Table table = CreateHtmlTable();
            table.CellPadding = 3;
            table.CellSpacing = 3;
            container.Controls.Add(table);
            object dataItem = (container as GridViewEditFormTemplateContainer).DataItem;
            bool editMode = SessParam.WorkOrderEditing;
            bool isClient = SessParam.IsClient;

            int row = 0;
            int col = mFirstCol;
            // Supplier Id 
            if (editMode)
                InsertEditBox(table, ref row, ref col, "adminDefault.Organizations", "ContractorIdTextBox", false,
                              dataItem, TableWorkOrder.cnContractorId, false);
            else
            {
                InsertSupplierComboBox(table, ref row, ref col, "adminDefault.Organizations",
                                       mContractorIdComboBox, true, true);
            }
            // Project
            InsertEditBox(table, ref row, ref col, "clientAddWo.Project", "ProjectTextBox", true, dataItem, TableWorkOrder.cnProject, false);

            // Client Work Order Number
            InsertEditBox(table, ref row, ref col, Dictionary.ClientWorkOrderNumber,
                          mClientWorkOrderNumberTextBox,
                          isClient,
                          dataItem, TableWorkOrder.cnCustomerWorkOrderNumber, SessParam.IsClient && !editMode);

            // Supplier Work Order Number
            InsertEditBox(table, ref row, ref col, Dictionary.SupplierWorkOrderNumber,
                          mContractorWorkOrderNumberTextBox,
                          !isClient,
                          dataItem, TableWorkOrder.cnContractorWorkOrderNumber, !SessParam.IsClient && !editMode);

            // Supplier Lot Number
            InsertEditBox(table, ref row, ref col, "ClienteditWoForm.ContractorLotNumber", "ContractorLotNumberNumberTextBox", true,
                dataItem, TableWorkOrder.cnContractorLotNumber, !editMode);
            // Sent Date
            InsertDate(table, ref row, ref col, "inventoryGrid.SendDateColumn", "SendDateTextBox", true, dataItem, TableWorkOrder.cnSendDate, !editMode);
            // Requested Delivery Date
            //if (editMode)
                InsertDate(table, ref row, ref col, "inventoryGrid.RequestedDelivaryColumn", "RequestedDelivaryDateTextBox",
                           isClient, dataItem, TableWorkOrder.cnRequestedDelivaryDate, false);
            // Planned Delivery Date
            //if (editMode)
                InsertDate(table, ref row, ref col, "inventoryGrid.PlannedDelivaryColumn", "PlannedDelivaryDateTextBox",
                           !isClient, dataItem, TableWorkOrder.cnPlannedDelivaryDate, false);
            // Actual Delivery Date
            if (editMode)
                InsertDate(table, ref row, ref col, "ContractorWoGrid.ActualDelivaryDate", "ActualDelivaryDateTextBox", 
                    true, dataItem, TableWorkOrder.cnActualDelivaryDate, false);
            // Customer Priority
            InsertSpinEdit(table, ref row, ref col, "ContractoreditWoForm.CustomerPriority", "CustomerPriorityTextBox",
                           isClient, dataItem, TableWorkOrder.cnCustomerPriority, false);
            // Quantity
            InsertEditBox(table, ref row, ref col, Dictionary.Quantity, mQuantityTextBox, !editMode, dataItem, TableWorkOrder.cnQuantity, !editMode);
            // Sent QTY
            if (editMode)
            {
                InsertLabel(table, row, ref col, "ClienteditWoForm.QuantitySentForDist", false);
                InsertTextBox(table, row, col, "", mSentQuantityTextBox, true);
                IncColRow(ref row, ref col);
            }
            // Customer Catalog Code
            InsertEditBox(table, ref row, ref col, "ContractoreditWoForm.CustomerCatalougeCode", "CustomerCatalougeCodeTextBox",
                          isClient,
                          dataItem, TableWorkOrder.cnCustomerCatalougeCode, false);
            // Supplier Catalog Code
            InsertEditBox(table, ref row, ref col, "ContractorAddWoFrm.ContractorCatalougeCode", "ContractorCatalogueCodeTextBox",
                          !isClient,
                          dataItem, TableWorkOrder.cnContractorCatalogueCode, false);
            // Product Description
            InsertEditBox(table, ref row, ref col, "InventoryGrid.ProductDescriptionColumn", "ProductDescriptionTextBox", 
                true, dataItem, TableWorkOrder.cnProductDescription, false);
            // Text Field A
            InsertEditBox(table, ref row, ref col, "ContractoreditWoForm.TextFieldA", "TextFieldATextBox", true, dataItem, TableWorkOrder.cnTextFieldA, false);
            // Text Field B
            // special case for Lithotech:
            if (SessParam.OrganizationId == 51)
            {
                InsertQCComboBox(table, ref row, ref col, "ContractoreditWoForm.TextFieldB", "TextFieldBTextBox", true, dataItem, false);
            }
            else
                InsertEditBox(table, ref row, ref col, "ContractoreditWoForm.TextFieldB", "TextFieldBTextBox", true, dataItem, TableWorkOrder.cnTextFieldB, false);
            // Text Field C
            InsertEditBox(table, ref row, ref col, "TextFieldC", "TextFieldCTextBox", true, dataItem, TableWorkOrder.cnTextFieldC, false);
            // Remarks
            InsertEditBox(table, ref row, ref col, "ContractoreditWoForm.Remarks", "RemarksTextBox", true, dataItem, TableWorkOrder.cnRemarks, false);
            // Customer Order Number
            InsertEditBox(table, ref row, ref col, "ContractoreditWoForm.OrderNumber", "OrderNumberTextBox", true, dataItem, TableWorkOrder.cnOrderNumber, false);
            // Supplier Approval
            InsertDate(table, ref row, ref col, "ClienteditWoForm.DateFieldA", "DateFieldATextBox", true, dataItem, TableWorkOrder.cnDateFieldA, false);
            // Customer Approval
            InsertDate(table, ref row, ref col, "ClienteditWoForm.DateFieldB", "DateFieldBTextBox", true, dataItem, TableWorkOrder.cnDateFieldB, false);
            // Original Requested Delivery Date 
            InsertDate(table, ref row, ref col, "ContractorEditWoForm.OriginalRequestedDeliveryDate", "OriginalRequestedDeliveryDateTextBox",
                !editMode, dataItem, TableWorkOrder.cnOriginalRequestedDeliveryDate, false);
            // Original Planned Delivery Date 
            InsertDate(table, ref row, ref col, "ContractorEditWoForm.OriginalPlannedDeliveryDate", "OriginalPlannedDeliveryDateTextBox",
              !isClient, dataItem, TableWorkOrder.cnOriginalPlannedDeliveryDate, false);
            // Customer Order Number 
            InsertEditBox(table, ref row, ref col, "ContractorEditWoForm.CustomerOrderNumber", "CustomerOrderNumberTextBox", true, dataItem,
                TableWorkOrder.cnCustomerOrderNumber, false);
            
            row++;
            int replacementCol = mFirstCol + 1;
            AddReplacement(table, row, replacementCol, GridViewTemplateReplacementType.EditFormUpdateButton);

            InsertLiteral(table, row, replacementCol, " | ");
            AddReplacement(table, row, replacementCol, GridViewTemplateReplacementType.EditFormCancelButton);
            string errorMessage = SessParam.EditFormErrorMessage;
            if (errorMessage != "")
            {
                ASPxLabel label = InsertLabelEx(table, row, replacementCol + 2, "ErrorMessageLabel", errorMessage, true);
                //label.ForeColor = Color.Red;
            }
        }

        private static void CheckRows(int row)
        {
            if (row >= mRowCount)
                throw new Exception("Not enough rows");
        }

        private static void InsertLiteral(Table table, int row, int col, string text)
        {
            Literal literal = new Literal();
            literal.Text = text;
            Add(table, row, col, literal);
        }

        private static void Add(Table table, int row, int col, Control child)
        {
            CheckRows(row);
            if (child is DropDownList)
                ((DropDownList)child).ControlStyle.ForeColor = Color.Black;
            table.Rows[row].Cells[col].Controls.Add(child);
        }

        private void AddReplacement(Table table, int row, int col,
                                    GridViewTemplateReplacementType replacementType)
        {
            ASPxGridViewTemplateReplacement tr = new ASPxGridViewTemplateReplacement();
            tr.ReplacementType = replacementType;
            Add(table, row, col, tr);
        }

        private static void IncColRow(ref int row, ref int col)
        {
            col = (col + mHalfColumnCount - 1) % mColumnCount;
            if (col == mFirstCol)
                row++;
        }

        private void InsertSpinEdit(Table table,
                                    ref int row, ref int col,
                                    string text,
                                    string id,
                                    bool enabled,
                                    object dataItem, string fieldName, bool must)
        {
            InsertLabel(table, row, ref col, text, must);
            ASPxSpinEdit spinEdit = new ASPxSpinEdit();
            spinEdit.NumberType = SpinEditNumberType.Integer;
            spinEdit.MinValue = int.MinValue;
            spinEdit.MaxValue = int.MaxValue;
            InsertControl(table, row, col, fieldName, spinEdit, id, enabled);
            spinEdit.Value = DataBinder.Eval(dataItem, fieldName);
            IncColRow(ref row, ref col);
        }

        private void InsertEditBox(Table table,
                                    ref int row,
                                    ref int col,
                                    string text,
                                    string id,
                                    bool enabled,
                                    object dataItem, string fieldName, bool must)
        {
            InsertLabel(table, row, ref col, text, must);
            InsertTextBox(table, row, col, id, enabled, dataItem, fieldName);
            IncColRow(ref row, ref col);
        }

        private void InsertDate(Table table,
                                 ref int row, ref int col,
                                 string text,
                                 string id,
                                 bool enabled,
                                 object dataItem, string fieldName, bool must)
        {
            InsertLabel(table, row, ref col, text, must);
            ASPxDateEdit dateEdit = new ASPxDateEdit();
            InsertControl(table, row, col, fieldName, dateEdit, id, enabled);

            dateEdit.MinDate = Utils.MinSqlDateTime;
            dateEdit.MaxDate = Utils.MaxSqlDateTime;

            dateEdit.Value = DataBinder.Eval(dataItem, fieldName);
            if (fieldName == "SendDate" && dateEdit.Value == null)
                dateEdit.Value = DateTime.Now;
            IncColRow(ref row, ref col);
        }

       
        protected static void SupplierComboBox_Init(object sender, EventArgs e)
        {
            int orgId = SessParam.OrganizationId;
            if (orgId == -1)
                return;

            List<TableOrganization> clients;

            //if (SessParam.IsClient)                                          17/07/2011
            //  clients = clsOrganization.GetClientsByContractorId(orgId);
            //else
            //  clients = clsOrganization.GetContractorsByClientId(orgId);
            if (SessParam.IsClient)
                clients = clsOrganization.GetContractorsByClientId(orgId);
            else
                clients = clsOrganization.GetClientsByContractorId(orgId);

            ASPxComboBox cb = (ASPxComboBox)sender;
            cb.DataSource = clients;
            cb.TextField = "OrganizationName";
            cb.ValueField = "OrganizationId";
            cb.ForeColor = Color.Black;
            cb.ItemStyle.ForeColor = Color.Black;
            cb.ListBoxStyle.ForeColor = Color.Black;
        }

        private void InsertSupplierComboBox(Table table,
                                            ref int row,
                                            ref int col,
                                            string text,
                                            string id,
                                            bool enabled, bool must)
        {
            InsertLabel(table, row, ref col, text, must);
            ASPxComboBox comboBox = new ASPxComboBox();
            SupplierComboBox_Init(comboBox, null);
            InsertControl(table, row, col, "", comboBox, id, enabled);
            IncColRow(ref row, ref col);
        }

        private void InsertQCComboBox(Table table,
                                            ref int row,
                                            ref int col,
                                            string text,
                                            string id,
                                            bool enabled, object dataItem, bool must)
        {
            InsertLabel(table, row, ref col, text, must);
            ASPxComboBox comboBox = new ASPxComboBox();
            string selectedValue = (DataBinder.Eval(dataItem, "TextFieldB") != null ? DataBinder.Eval(dataItem, "TextFieldB").ToString() : "before QC");
            List<string> values = new List<string>(new string[] { "before QC","in process","QC" });
            if (!values.Contains(selectedValue))
                values.Add(selectedValue);
            comboBox.DataSource = values;
            comboBox.Value = selectedValue;
            comboBox.ForeColor = Color.Black;
            comboBox.ItemStyle.ForeColor = Color.Black;
            comboBox.ListBoxStyle.ForeColor = Color.Black;

            InsertControl(table, row, col, "TextFieldB", comboBox, id, enabled);
            IncColRow(ref row, ref col);
        }

        private ASPxTextBox InsertTextBox(Table table, int row, int col,
                                          string fieldName,
                                          string id, bool enabled)
        {
            ASPxTextBox textBox = new ASPxTextBox();
            InsertControl(table, row, col, fieldName, textBox, id, enabled);
            return textBox;
        }

        private void InsertControl(Table table, int row, int col,
                                   string fieldName,
                                   ASPxTextBoxBase control,
                                   string id, bool enabled)
        {
            InsertControlEx(table, row, col, fieldName, control, id, enabled, mEditWidth);
        }

        private void InsertControlEx(Table table, int row, int col,
                                     string fieldName,
                                     ASPxTextBoxBase control,
                                     string id, bool enabled, int width)
        {
            control.ID = id;
            control.Width = width;
            mEditFormDictionary.Add(id, new EditFormControl() { mControl = control, mFieldName = fieldName });

            if (!enabled)
            {
                control.Enabled = enabled;
                //control.CssFilePath = @"~/MLY/Style/DevExpress_Style.css";
                //control.CssPostfix = "DisabledEditBox";
                control.DisabledStyle.BackColor = Color.Silver;
                control.DisabledStyle.ForeColor = Color.Blue;
            }
            Add(table, row, col, control);
        }

        private Control GetControl(string fieldName)
        {
            foreach (KeyValuePair<string, EditFormControl> kvp in mEditFormDictionary)
            {
                EditFormControl editFormControl = (EditFormControl)kvp.Value;
                if (editFormControl.mFieldName == fieldName)
                {
                    return editFormControl.mControl;
                }
            }
            return null;
        }

        public DateTime? GetDate(string fieldName)
        {
            Control control = GetControl(fieldName);
            if (control is ASPxDateEdit)
            {
                ASPxDateEdit dateEdit = (ASPxDateEdit)control;
                return dateEdit.Date;
            }
            return null;
        }

        private void InsertTextBox(Table table,
                                   int row, int col,
                                   string id,
                                   bool enabled,
                                   object dataItem, string fieldName)
        {
            ASPxTextBox textBox = InsertTextBox(table, row, col, fieldName, id, enabled);
            textBox.Value = DataBinder.Eval(dataItem, fieldName);
        }

        private static ASPxLabel InsertLabel(Table table, int row, ref int col, string text, bool must)
        {
            ASPxLabel label = InsertLabelEx(table, row, col, null,
                                            " " + Dictionary.Translate(text) + ":", must);
            col++;
            return label;
        }

        private static ASPxLabel InsertLabelEx(Table table, int row, int col, string id, string text, bool must)
        {
            ASPxLabel label = new ASPxLabel();
            if (!string.IsNullOrEmpty(id))
                label.ID = id;
            label.Text = text;
            if (must) label.ForeColor = Color.Red;
            label.Width = mLabelWidth;
            Add(table, row, col, label);
            return label;
        }

        private static Table CreateHtmlTable()
        {
            Table table = new Table();
            table.CellPadding = 3;
            for (int row = 0; row < mRowCount; row++)
                CreateEmptyRow(table, row);
            return table;
        }

        private static void CreateEmptyRow(Table table, int row)
        {
            table.Rows.Add(new TableRow());

            TableCell[] tableCells = new TableCell[mColumnCount];
            for (int i = 0; i < mColumnCount; i++)
            {
                TableCell cell = new TableCell();
                cell.HorizontalAlign = HorizontalAlign.Left;
                tableCells[i] = cell;
            }
            table.Rows[row].Cells.AddRange(tableCells);
        }

    }
}
